package com.yingjia.yingjiauniversity.json.gson;

import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.yingjia.basic.json.constant.DateFormatConstant;

import java.lang.reflect.Modifier;
import java.text.DateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <Gson实现工厂类>
 *
 * @author: guoxiangxun
 * @date: 15-11-26 下午4:37
 * @version: v1.0
 */
public class GsonFactory {

    public static Gson build(final String[] fieldExclusions, final Class<?>[] classExclusions, String dateFormat) {
        GsonBuilder b = createBuilder();
        b.addSerializationExclusionStrategy(new ExclusionStrategy() {
            @Override
            public boolean shouldSkipField(FieldAttributes f) {
                if (fieldExclusions == null
                        || fieldExclusions.length == 0) {
                    return false;
                }
                //遍历查询是否需要跳过转换
                for (String field : fieldExclusions) {
                    if (field.equals(f.getName())) {
                        return true;
                    }
                }
                return false;
            }

            @Override
            public boolean shouldSkipClass(Class<?> clazz) {
                if (classExclusions == null
                        || classExclusions.length == 0) {
                    return false;
                }
                //遍历查询是否需要跳过转换
                for (Class c : classExclusions) {
                    if (c.equals(clazz)) {
                        return true;
                    }
                }
                return false;
            }
        });
        Gson gson = create(b, dateFormat);
        return gson;
    }

    /**
     * <创建基本的Gson对象>
     *
     * @return the gson
     * @author: guoxiangxun
     * @date: Nov 26, 2015 5:06:33 PM
     * @version: v1.0
     */
    public static Gson build() {
        GsonBuilder b = createBuilder();
        return create(b, null);
    }

    /**
     * <创建Gson对象>
     *
     * @param b          the b
     * @param dateFormat the date format
     * @return the gson
     * @author: guoxiangxun
     * @date: Jul 7, 2016 6:39:57 PM
     * @version: v1.0
     */
    private static Gson create(GsonBuilder b, String dateFormat) {

        if (dateFormat != null) {
            b.setDateFormat(dateFormat);
        } else {
            b.registerTypeAdapter(Date.class, new DateSerializer()).setDateFormat(DateFormat.LONG);
            b.registerTypeAdapter(Date.class, new DateDeserializer()).setDateFormat(DateFormat.LONG);
        }
        ListDeserializer listDeserializer = new ListDeserializer();
        MapDeserializer mapDeserializer = new MapDeserializer();
        Gson gson = b.registerTypeAdapter(Map.class, mapDeserializer)
                .registerTypeAdapter(List.class, listDeserializer)
                .create();
        listDeserializer.setGson(gson);
        mapDeserializer.setGson(gson);

        return gson;
    }

    /**
     * <创建GsonBuilder>
     *
     * @return the gson builder
     * @author: guoxiangxun
     * @date: Nov 26, 2015 5:03:03 PM
     * @version: v1.0
     */
    private static GsonBuilder createBuilder() {
        GsonBuilder b = new GsonBuilder();
        b.serializeNulls().setDateFormat(DateFormatConstant.FULL_DATE_FORMAT)//时间转化为特定格式
//                .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)//会把字段首字母大写,注:对于实体上使用了@SerializedName注解的不会生效.
//                .setPrettyPrinting(); //对json结果格式化.
                .excludeFieldsWithModifiers(
                        Modifier.FINAL,
                        Modifier.TRANSIENT,
                        Modifier.STATIC);
        return b;
    }
}
